# Copyright 2012 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Simple App Engine app for detecting behavior of JSON caching in iframes.

Point your browser at an instance of this app at the root page and a demo
page will load which prefetches JSON then creates an iframe which requests
the same JSON. The random numbers and timestamp inside the iframe should
match those outside of the iframe to indicate that the request was not
reissued. You may also want to watch the logging output as pages are
loaded to see if duplicate requests are made for the same JSON URL.
"""

import logging
import os
import random
import time

from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

__author__ = 'j.s@google.com (Jeff Scudder)'


class JsonPrefetchDemoServer(webapp.RequestHandler):
  def get(self):
    # Cache in the browser for an hour.
    self.response.headers['Cache-Control'] = 'private, max-age=3600'
    self.response.headers['Content-Type'] = 'text/html'
    # See lib.js to understand how we're requesting the JSON and iframe.
    self.response.out.write("""<!DOCTYPE html>
      <html>
        <head>
          <script src="/lib.js"></script>
        </head>
        <body>
          (A <a href="http://www.example.com/">link</a>
           for checking the back button.)<br>
          <div id="output"></div>
          <div id="iframe-container"></div>
          <script>
            window['parentClient'] = new jt.Client();
            window['parentClient'].generateNewRequestId();
            window['parentClient'].parentFetchJson();
          </script>
          <div>End of parent page.</div>
        </body>
      </html>""")


class JsonServer(webapp.RequestHandler):
  def get(self):
    # Delay response to see effect of terrible network latency.
    time.sleep(1)
    # Cache locally in the browser for 5 minutes.
    self.response.headers['Cache-Control'] = 'public, max-age=300'
    self.response.headers['Pragma'] = 'public'
    self.response.headers['ETag'] = str(random.randint(0, 500000))
    self.response.headers['Content-Type'] = 'text/javascript'
    # See the code in lib.js to see what we're calling.
    logging.info('JSON Request headers:')
    for key in self.request.headers:
      logging.info('*    ' + key + ': ' + self.request.headers[key])
    self.response.out.write(
        'renderJson('
        '"rand: ' + str(random.randint(0, 500000)) +
        ' request: ' + self.request.get('currentId') +
        ' time: ' + str(int(round(time.time() * 1000))) + '");')


class IFrameWithJsonServer(webapp.RequestHandler):
  def get(self):
    # Delay response to see effect of terrible network latency.
    time.sleep(1)
    # Cache in the browser for an hour.
    self.response.headers['Cache-Control'] = 'private, max-age=3600'
    self.response.headers['Content-Type'] = 'text/html'
    # See lib.js to understand how we're requesting the JSON.
    self.response.out.write("""<!DOCTYPE html>
      <html>
        <head>
          <script src="/lib.js"></script>
        </head>
        <body>
          <div id="output"></div>
          <script>
            // Gets the ID from the request URL.
            var client = new jt.Client();
            client.childFetchJson();
          </script>
          <div>End of child iframe.</div>
        </body>
      </html>""")


class LibServer(webapp.RequestHandler):
  def get(self):
    # Cache in the browser for an hour.
    self.response.headers['Cache-Control'] = 'private, max-age=3600'
    self.response.headers['Content-Type'] = 'text/javascript'
    path = os.path.join(os.path.dirname(__file__), 'lib.js')
    self.response.out.write(template.render(path, {}))


application = webapp.WSGIApplication(
    [('/', JsonPrefetchDemoServer),
     ('/jsonData.js', JsonServer),
     ('/jsonIframe', IFrameWithJsonServer),
     ('/lib.js', LibServer)],
    debug=True)


def main():
  run_wsgi_app(application)


if __name__ == '__main__':
  main()
